package cc.telecomdigital.tdstock.trading;

import java.util.ArrayList;

import com.lightstreamer.ls_client.UpdateInfo;

import cc.telecomdigital.tdstock.R;
import cc.telecomdigital.tdstock.Framework.Application_Framework.LS_ItemRequestType;
import cc.telecomdigital.tdstock.Framework.UniqueItem.TDStockLog;
import cc.telecomdigital.tdstock.Services.LS_SubscriptionItem;
import cc.telecomdigital.tdstock.Services.LS_UserClient.CONNECTION_STATUS;
import cc.telecomdigital.tdstock.Services.LS_UserClient.ILS_UserClient_Authentication_Report;
import cc.telecomdigital.tdstock.Services.LS_UserClient.ILS_UserClient_Response;
import cc.telecomdigital.tdstock.Services.LS_UserClient.LS_UserClient_Authentication_Result;
import cc.telecomdigital.tdstock.trading.Common.Trade_AppConstant;
import cc.telecomdigital.tdstock.trading.Common.Trade_StockPortfolioRecord;
import cc.telecomdigital.tdstock.trading.Services.TradeAppInfo;
import cc.telecomdigital.tdstock.trading.Services.TradeGetPortfolio;
import cc.telecomdigital.tdstock.trading.Services.TradeGetPortfolio.ITradeGetPortfolioResponse;
import cc.telecomdigital.tdstock.trading.Services.TradeGetPortfolio.TradeGetPortfolioResult;
import cc.telecomdigital.tdstock.trading.Tools.Trade_StockFunctionTools;
import cc.telecomdigital.tdstock.trading.widget.AppDialogOK;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.WindowManager.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

public class Trade_AcctBalance_SubActivity extends Trade_TemplateActivity
	implements View.OnClickListener, ILS_UserClient_Response
{
	// List Item Style Object
	private enum TextAlign
	{
		LEFT, RIGHT, CENTER
	}

	private class TextItem
	{
		public String		text;
		public TextAlign	alignment;
		public int		colorCode;

		public TextItem(String iText, TextAlign iAlign, int iColorCode)
		{
			text = iText;
			alignment = iAlign;
			colorCode = iColorCode;
		}

		public TextItem(String iText)
		{
			text = iText;
			alignment = TextAlign.LEFT;
			colorCode = getResources().getColor(R.color.Black);
		}
	}

	/** Text Adapter to display the inforamtion of the account status **/
	private class TextItemAdapter extends ArrayAdapter<TextItem>
	{
		// Reference to the Item List
		private int	itemLayout;

		public TextItemAdapter(Context iContext, int iItemLayout, ArrayList<TextItem> iItemList)
		{
			super(iContext, iItemLayout, iItemList);			
			itemLayout = iItemLayout;
		}

		@Override
		public View getView(int iPosition, View iContextView,
				ViewGroup iParent)
		{
			View viewObj = iContextView;
			if (viewObj == null)
			{
				LayoutInflater inflatObj = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				viewObj = inflatObj.inflate(itemLayout, null);
				viewObj.setClickable(false);				
			}

			TextItem item;

			item = this.getItem(iPosition);
			if (item != null)
			{
				TextView textViewObj = (TextView) viewObj
						.findViewById(R.id.view_textitemlist_Text);
				if (textViewObj != null)
				{
					textViewObj.setTextColor(item.colorCode);
					textViewObj.setText(item.text);
					if (item.alignment == TextAlign.CENTER)
						textViewObj.setGravity(Gravity.CENTER);
					else if (item.alignment == TextAlign.LEFT)
						textViewObj.setGravity(Gravity.CENTER_VERTICAL
								| Gravity.LEFT);
					else if (item.alignment == TextAlign.RIGHT)
						textViewObj.setGravity(Gravity.CENTER_VERTICAL
								| Gravity.RIGHT);
				}
			}
			return viewObj;
		}
	}

	private ArrayList<TextItem>	acctResultList;
	private ListView			acctResultView;
	// Create the array adapter to bind the array to the list view
	private TextItemAdapter		textItemAdapter;

	@Override
	public void onCreate(Bundle iSaveInstance)
	{
		super.onCreate(iSaveInstance);
		setContentView(R.layout.account_balance);
		// Map the button function
		// Set Header as UserName
		TextView textViewObj = (TextView) findViewById(R.id.view_acctheader_Title);
		if (TradeAppInfo.IsDemoAccount())
			textViewObj.setText(TradeAppInfo.GetUserName());
		else
			textViewObj.setText(R.string.acctBalText);

		ImageButton imgButton;

		imgButton = (ImageButton) findViewById(R.id.view_acctheader_Refresh);
		imgButton.setVisibility(View.VISIBLE);
		imgButton.setOnClickListener(this);

		imgButton = (ImageButton) findViewById(R.id.view_acctheader_Home);
		imgButton.setOnClickListener(this);

		acctResultList = new ArrayList<TextItem>();

		textItemAdapter = new TextItemAdapter(this,
							R.layout.view_textitemlist, acctResultList);
		acctResultView = (ListView) findViewById(R.id.acctBalance_List);
		acctResultView.setDividerHeight(0);		
		acctResultView.setAdapter(textItemAdapter);
		acctResultView.setSelector(R.drawable.Transparent);
	}

	@Override
	protected void onResume()
	{
		super.onResume();	
		if (TradeAppInfo.IsStockPortfolioRecordEmpty() == false)
		{
			InformationRefresh();
			SubscribeAccountHold();
		}			
		else
			StockBalanceDataRequest();
	}

	@Override
	protected void onPause()
	{
		DetachedDisconnectMessage();	
		super.onPause();
	}

	@Override
	public void onBackPressed()
	{
		SwitchFreeActivity(Trade_tradingOptionActivity.class);
	}	
	
	@Override
	public void onClick(View iViewObj)
	{
		int objID;

		objID = iViewObj.getId();
		switch (objID)
		{
			case R.id.view_acctheader_Home:
				SwitchFreeActivity(Trade_tradingOptionActivity.class);
				break;

			case R.id.view_acctheader_Refresh:
				iViewObj.setClickable(false);	
				StockBalanceDataRequest();
				iViewObj.setClickable(true);					
				break;
		}
	}

	/** Refresh of the information, either get from the memory or request from server again **/
	private void InformationRefresh()
	{
		boolean isNegative;
		String  cashBalance;
		String  usdBalance;
		String  cnyBalance;
		String  closeBalance;
		String  purchaseBalance;
		String  tmpString;

		Trade_StockPortfolioRecord portfolioInfo;

		portfolioInfo = TradeAppInfo.GetStockPortfolioRecord();
		if (portfolioInfo != null)
		{
			// Hong Kong Dollar
			isNegative = false;
			tmpString = portfolioInfo.GetHKDCashBalance();
			
			tmpString = Trade_StockFunctionTools.AutoFormatPriceToCents(tmpString);
			if (tmpString.startsWith("-"))
			{
				isNegative = true;
				tmpString = tmpString.substring(1, tmpString.length());
			}
							
			cashBalance = "";
			if (isNegative)
				cashBalance += "-";
				
			cashBalance += TradeAppInfo.HKDSign + Trade_StockFunctionTools.AddFormatToThousand(tmpString);
			
			// CNY Dollar
			isNegative = false;
			tmpString = portfolioInfo.GetCNYCashBalance();
			
			tmpString = Trade_StockFunctionTools.AutoFormatPriceToCents(tmpString);
			if (tmpString.startsWith("-"))
			{
				isNegative = true;
				tmpString = tmpString.substring(1, tmpString.length());
			}			
			
			cnyBalance = "";
			if (isNegative)
				cnyBalance += "-";
			cnyBalance += TradeAppInfo.CNYSign + Trade_StockFunctionTools.AddFormatToThousand(tmpString);
			
			// USD Dollar
			isNegative = false;
			tmpString = portfolioInfo.GetUSDCashBalance();
			/* we decide not to show the USD cash if it has no meaningful value */
			if (tmpString.equals("0.00"))
				usdBalance = null;
			else
			{
				tmpString = Trade_StockFunctionTools.AutoFormatPriceToCents(tmpString);
				if (tmpString.startsWith("-"))
				{
					isNegative = true;
					tmpString = tmpString.substring(1, tmpString.length());
				}
				usdBalance = "";
				if (isNegative)
					usdBalance += "-";
				usdBalance += TradeAppInfo.USDSign + Trade_StockFunctionTools.AddFormatToThousand(tmpString);				
			}			
			
			//The other values
			closeBalance = Trade_StockFunctionTools.AutoFormatPriceToCents(portfolioInfo.closeBalance);
			closeBalance = TradeAppInfo.HKDSign + Trade_StockFunctionTools.AddFormatToThousand(closeBalance);
			purchaseBalance = Trade_StockFunctionTools.AutoFormatPriceToCents(portfolioInfo.purchasePowerBalance);
			purchaseBalance = TradeAppInfo.HKDSign+ Trade_StockFunctionTools.AddFormatToThousand(purchaseBalance);
		}
		else
		{
			cashBalance  = "---";
			//USD is exceptional
			usdBalance   = null;
			cnyBalance   = "---";
			closeBalance = "---";
			purchaseBalance = "---";
		}
		
		acctResultList.clear();
		// Add a dummy line for view adjustment
		acctResultList.add(new TextItem(null));

		acctResultList.add(new TextItem(getString(R.string.amountAvailText)
				+ ":", TextAlign.LEFT, getResources().getColor(
				R.color.Orange)));
		acctResultList.add(new TextItem(cashBalance, TextAlign.RIGHT,
				getResources().getColor(R.color.White)));
		acctResultList.add(new TextItem(cnyBalance, TextAlign.RIGHT,
				getResources().getColor(R.color.DimYellow)));

		//No need to add if it is null
		if (usdBalance != null)
			acctResultList.add(new TextItem(usdBalance, TextAlign.RIGHT,
					getResources().getColor(R.color.DimYellow)));	

		acctResultList.add(new TextItem(getString(R.string.lastBalanceText)
				+ ":", TextAlign.LEFT, getResources().getColor(
				R.color.Orange)));
		acctResultList.add(new TextItem(closeBalance, TextAlign.RIGHT,
				getResources().getColor(R.color.White)));

		acctResultList.add(new TextItem(getString(R.string.fundTradingText)
				+ ":", TextAlign.LEFT, getResources().getColor(
				R.color.Orange)));
		acctResultList.add(new TextItem(purchaseBalance, TextAlign.RIGHT,
				getResources().getColor(R.color.White)));

		textItemAdapter.notifyDataSetChanged();
		acctResultView.setSelectionAfterHeaderView();
	}

	static private final int	REFRESH_CONTENT	= 1;

	@Override
	public boolean onCreateOptionsMenu(Menu iMenu)
	{
		super.onCreateOptionsMenu(iMenu);
		// Add the menu Item to the menu
		MenuItem menuItemObj = iMenu.add(0, REFRESH_CONTENT, Menu.NONE,
				R.string.updateText);
		menuItemObj.setIcon(R.drawable.ic_menu_lrefresh);
		menuItemObj.setShortcut('0', 'r');

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem iMenu)
	{
		super.onOptionsItemSelected(iMenu);
		switch (iMenu.getItemId())
		{
			case REFRESH_CONTENT:
				StockBalanceDataRequest();
				return true;
		}
		return false;
	}

	private AppDialogOK promptMessage = null;
	private void ShowPromptMessage(String iContent)
	{
		if (promptMessage != null)
			promptMessage.dismiss();
		
		DismissWaitingDialog();
		promptMessage = ShowInfoBox(iContent);
	}

	/** Internal Request Data from server **/
	private boolean StockBalanceDataRequest()
	{
		if (TradeAppInfo.IsDemoAccount() == false)
		{
			if (IsNetworkAvailable() == false)
			{
				ShowPromptMessage(getString(R.string.commErrorText));
				SubscribeAccountHold();
				return false;
			}
	
			if (TradeAppInfo.HasSessionTimeExpired())
			{
				ShowTimeExpiredBox();
				return false;
			}
		}

		if (promptMessage != null)
			promptMessage.dismiss();		
		ShowWaitingDialog();

		final TradeGetPortfolio portRequest;

		portRequest = new TradeGetPortfolio(actContext);
		portRequest.SetUserInformation(TradeAppInfo.GetUserName());

		portRequest.SendRequest(TradeAppInfo.IsDemoAccount(),
				new ITradeGetPortfolioResponse()
				{
					@Override
					public void ResponseFunc(boolean iSuccessfulSend,
							TradeGetPortfolioResult iResponse)
					{
						if (iSuccessfulSend == false)
							ShowPromptMessage(getString(R.string.commErrorText));
						else
							HandleGetPortfolioResult(iResponse);
						// Subscribe after first download
						SubscribeAccountHold();
						portRequest.Dispose();
					}
				});
		return true;
	}

	/** Handle when data comes in **/
	private void HandleGetPortfolioResult(TradeGetPortfolioResult iResult)
	{
		AppDialogOK promptDialog;

		promptDialog = null;
		if ((iResult.BrokerMessage != null)
				&& (iResult.BrokerMessage.length() != 0))
		{
			promptDialog = new AppDialogOK(this);
			promptDialog.SetTextContent(iResult.BrokerMessage);
			promptDialog.SetButtonText(R.string.okText);
			// return features are based on specification
		}

		// Login Session expired and kick user out to the login page
		if (iResult.StatusCode.equals("12"))
		{
			DismissWaitingDialog();
			// Back to the previous window, the trading option
			if (promptDialog != null)
			{
				promptDialog.show(new AppDialogOK.IAppDialogOK()
				{
					@Override
					public void OnDialogCancel(DialogInterface iDialog)
					{
						SetToLoginActivity();
					}

					@Override
					public void OnOK_Click(DialogInterface iDialog)
					{
						SetToLoginActivity();
					}

				}, true);
				return;
			}
			
			SetToLoginActivity();
			return;
		}

		if (iResult.StatusCode.equals("0"))
		{
			// Set the Data to the Database
			TradeAppInfo.SetStockPortfolioRecord(iResult.portfolio);
			InformationRefresh();
			DismissWaitingDialog();
			return;
		}

		DismissWaitingDialog();
		if (promptDialog != null)
			promptDialog.show(null, true);
	}

	/* Subscribing for Account on hold invoking by the server */
	private String lsAccountHoldRequest = null;
	private final String AccountChangeSchema = "CMD";
	private void SubscribeAccountHold()
	{
		if (debugMode)
			TDStockLog.i(GetIdentity(), "*** SubscribeAccountHold");
		
		if (TradeAppInfo.IsDemoAccount() == true)
				return;
		
		//Now we are using light streamer		
		LS_SubscriptionItem quoteItem;
		String              deviceID;
		
		deviceID = TradeAppInfo.GetDeviceID(actContext);
		if (lsAccountHoldRequest == null)
			lsAccountHoldRequest = LSGetUniqueID();
		
		quoteItem = new LS_SubscriptionItem("TRADING");
		quoteItem.AddSubscribeItem(deviceID);
		quoteItem.AddSubscribeSchema(AccountChangeSchema);		

		if (LightStreamerSubscribeItem(lsAccountHoldRequest, quoteItem, LS_ItemRequestType.NONE, this) == false)
		{		
			ShowPromptMessage(getString(R.string.SubscribeError_Text));
			return;
		}		
	}

	private Handler UIHandler = new Handler();
	@Override
	public void onUpdate(String iIdentifier, int iSchemaIndex,
			String iSchemaValue, UpdateInfo iUpdateInfo)
	{
		String   tmpValue, tmpValue2;
		String[] stringArray;

		tmpValue = iUpdateInfo.getNewValue(AccountChangeSchema);
		//Fault
		if ((tmpValue == null) || (tmpValue.length() == 0))
			return;

		if (debugMode)
			TDStockLog.i(GetIdentity(), "AccountUpdate: " + tmpValue);
		stringArray = tmpValue.split(" ");

		int    index, count;

		count = stringArray.length;
		//Sample o:1234 p:2121
		//We are at the account book, so we will look at the data again		
		for (index = 0; index < count; index++)
		{
			tmpValue  = stringArray[index].trim();
			/* Get the data after the : */
			if (tmpValue.startsWith("o:"))
			{
				tmpValue2 = tmpValue.substring(2);
				if (tmpValue2.equals("0") == false)
				{
					TradeAppInfo.ClearStockHistoryRecord();
					if (debugMode)
						TDStockLog.i(GetIdentity(), "Order book will be needed to updated.");
				}
			}
			else if (tmpValue.startsWith("p:"))
			{
				tmpValue2 = tmpValue.substring(2);	
				if (tmpValue2.equals("0") == false)
				{
					TradeAppInfo.ClearStockPortfolioRecord();				
					if (debugMode)
						TDStockLog.i(GetIdentity(), "Portfolio will be needed to updated.");
				}
			}
		}

		/* Just look at what we need here, There is UI involve and that's why we use UIHandle post */
		if (TradeAppInfo.IsStockPortfolioRecordEmpty())
		{
			Runnable runObject = new Runnable()
			{
				public void run()
				{
					StockBalanceDataRequest();
				}
			};
			UIHandler.post(runObject);
		}
	}

	@Override
	public void LS_UserClient_ConnectionReport(CONNECTION_STATUS iStatus)
	{
		if (TradeAppInfo.IsDemoAccount())
			return;

		if (debugMode)
			TDStockLog.i(GetIdentity(), "LS_UserClient_ConnectionReport: status="+ iStatus);

		//Return to the sign in message display for the application
		if (iStatus == CONNECTION_STATUS.CLOSE_BY_FORCE)
		{
			SetToAppLoginActivity();
			return;	
		}

		boolean isConnected;

		if (iStatus == CONNECTION_STATUS.CONNECTED)
			isConnected = true;
		else
			isConnected = false;

		//Set a dummy ui to the display
		if (isConnected)
			DetachedDisconnectMessage();
		else
		{
			DismissWaitingDialog();			
			AttachDisconnectMessage();
		}		
	}

	private PopupWindow lsStatusPopupView = null;
	private View        viewObj = null;
	private Runnable popupWindow_runnable = null;
	private void AttachDisconnectMessage()
	{
		if (lsStatusPopupView == null)
		{
			LayoutInflater inflatObj = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

			viewObj  = inflatObj.inflate(R.layout.trade_prompt_msgbox, null);
			viewObj.findViewById(R.id.prompt_msgboxContent).setOnClickListener( new OnClickListener()
			{
				@Override
				public void onClick(View arg0)
				{
					boolean status;

					status = appHost.LSClient_Connect(new ILS_UserClient_Authentication_Report()
					{
						@Override
						public void LS_UserClient_Authentication_Response(
								LS_UserClient_Authentication_Result iResponse)
						{
							if ((iResponse.successfulSend == false) || (iResponse.statusCode == null) 
								|| !iResponse.statusCode.equals("0"))
							{
								UIHandler.postDelayed(popupWindow_runnable, Trade_AppConstant.timeDelayForPopup);
								return;
							}											
						}											
					});											
					if (status == true)
						DetachedDisconnectMessage();
				}
			});

			lsStatusPopupView = new PopupWindow(viewObj, 
									 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
			lsStatusPopupView.setAnimationStyle(R.anim.zoom_enter);
			lsStatusPopupView.setOutsideTouchable(true);			
		}

		if (!lsStatusPopupView.isShowing())
		{
			if (popupWindow_runnable == null)
			{
				popupWindow_runnable = new Runnable()
				{
					public void run()
					{
						lsStatusPopupView.showAtLocation( viewObj, Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 
												    0, Trade_AppConstant.popupHeightAboveLoc);	
					};
				};
			}
			UIHandler.postDelayed(popupWindow_runnable, Trade_AppConstant.timeDelayForPopup);				
		}			
	}	

	private void DetachedDisconnectMessage()
	{
		if (lsStatusPopupView == null)
			return;

		if (popupWindow_runnable != null)
			UIHandler.removeCallbacks(popupWindow_runnable);

		if (lsStatusPopupView.isShowing())
			lsStatusPopupView.dismiss();
	}

	@Override
	public void ReporterTicker_Response(int iRemainSecond)
	{	}
}
